#include "mystdio.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#define TRY_FLUSH 1
#define MUST_FLUSH 2

myFILE* myfopen(const char* pathname,const char* mode)
{
  int fd = -1;
  int open_mode = 0;
  if(strcmp(mode,"r") == 0)
  {
    open_mode = O_RDONLY;
    fd = open(pathname,open_mode);
  }
  else if(strcmp(mode,"w") == 0)
  {
    open_mode = O_WRONLY|O_CREAT|O_TRUNC;
    fd = open(pathname,open_mode,MODE);
  }
  else if(strcmp(mode,"a") == 0)
  {
    open_mode = O_WRONLY|O_CREAT|O_APPEND;
    fd = open(pathname,open_mode,MODE);
  }
  else{

  }
  if(fd < 0)
  {
    return NULL;
  }
  myFILE* fp = (myFILE*)malloc(sizeof(myFILE));
  if(fp == NULL)
  {
    return NULL;
  }
  fp->fd = fd;
  fp->flush_mode = LINE_BUFFER;
  fp->open_mode = open_mode;
  fp->cap = SIZE;
  fp->pos = 0;
  
  return fp;

}
static void myfflushcore(myFILE* fp,int flag)
{
  if(fp->pos == 0)
  {
    return;
  }
  if(flag == MUST_FLUSH)
  {
    write(fp->fd,fp->outbuffer,fp->pos);
    fp->pos = 0;
  }
  else{
    if((fp->flush_mode & LINE_BUFFER )&& fp->outbuffer[fp->pos - 1] == '\n')
    {
      write(fp->fd,fp->outbuffer,fp->pos);
      fp->pos = 0;
    }
    if((fp->flush_mode & FULL_BUFFER) && (fp->cap == fp->pos))
    {
      write(fp->fd,fp->outbuffer,fp->pos);
      fp->pos = 0;
    }
    if(fp->flush_mode & NON_BUFFER)
    {
      write(fp->fd,fp->outbuffer,fp->pos);
      fp->pos = 0;
    }
  }

}



int myfputs(const char* str,myFILE* fp)
{
  if(strlen(str) == 0)
  {
    return 0;
  }
  // 向文件缓冲区写 注意pos位置
  memcpy(fp->outbuffer + fp->pos,str,strlen(str));
  fp->pos += strlen(str);

  //自己刷新到内核
  myflush(fp);

  return strlen(str);
}

void myflush(myFILE* fp)
{
  myfflushcore(fp,TRY_FLUSH);
}


void myfclose(myFILE* fp)
{
  myfflushcore(fp,MUST_FLUSH);

  close(fp->fd);
  free(fp);
}
